Skip to content

Add readOnlyHint MCP tool annotations to Memgraph MCP server#213

Open
bbartels wants to merge 3 commits into
memgraph:mainfrom
bbartels:main
Open

Add readOnlyHint MCP tool annotations to Memgraph MCP server#213
bbartels wants to merge 3 commits into
memgraph:mainfrom
bbartels:main

Conversation

@bbartels

@bbartels bbartels commented Jul 3, 2026

Copy link
Copy Markdown

The Memgraph MCP server enforced read-only mode at runtime but never advertised readOnlyHint in tool metadata, leaving MCP clients unable to distinguish read-only tools from potentially mutating ones.

Changes

server.py — tool annotation updates

  • 12 definitively read-only tools decorated with @mcp.tool(annotations={"readOnlyHint": True}):
    list_databases, get_configuration, get_index, get_constraint, get_schema, get_storage, get_triggers, get_procedures, get_betweenness_centrality, get_page_rank, get_node_neighborhood, search_node_vectors
  • run_query uses readOnlyHint=READ_ONLY_MODE — the hint mirrors the runtime MCP_READ_ONLY env var so clients see accurate metadata in both modes:
    @mcp.tool(annotations={"readOnlyHint": READ_ONLY_MODE})
    def run_query(query: str, ctx: Context | None = None) -> list[dict[str, Any]]:
  • use_database left unannotated — it mutates session state even though it doesn't write to the graph.

Uses FastMCP 3.x dict-style annotation API (annotations={"readOnlyHint": ...}), which maps directly to mcp.types.ToolAnnotations.

tests/test_tool_annotations.py — new test file

15 unit tests verifying:

  • All 12 read-only tools expose readOnlyHint=True
  • use_database does not have readOnlyHint=True
  • run_query exposes readOnlyHint=True when MCP_READ_ONLY=true and readOnlyHint is not True when MCP_READ_ONLY=false

@bbartels bbartels requested a review from antejavor as a code owner July 3, 2026 11:46
@CLAassistant

CLAassistant commented Jul 3, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ bbartels
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

@antejavor

antejavor commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Hi @bbartels, thanks a lot for the feedback and proposed changes, just heads up, we are seriously refactoring current MCP setup -> #211

Tools are changing heavily, would you be wiling to adapt this PR once we merge #221 to main? Timing 😅

@bbartels

bbartels commented Jul 3, 2026

Copy link
Copy Markdown
Author

@antejavor Oh I see, happy to! Alternatively feel free to just make this change there as well if it would be more convenient :)

@bbartels

bbartels commented Jul 3, 2026

Copy link
Copy Markdown
Author

The main reason we need this is that it informs our mcp gateway whether or not a tool should be invokable from a readonly context!

@bbartels

bbartels commented Jul 3, 2026

Copy link
Copy Markdown
Author

Also just a note, the cla requires a full address, feel like that might be a bit intrusive for some individuals

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants